package DB;

import Model.Scenario;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 * ScenarioManager manages database operations related to Scenario class
 * @author V3nom
 */
public class ScenarioManager implements IFScenarioManager {

    //SQL queries
    private static final String GET_ALL_SCENARIOS = "SELECT * FROM scenario";
    private static final String SAVE_SCENARIO = "INSERT INTO scenario "
            + "VALUES(?,GETDATE())";
    private static final String UPDATE_SCENARIO = "UPDATE scenario SET alias=?"
            + " WHERE scenarioId=?";
    private static final String DELETE_SCENARIO = "DELETE FROM scenario"
            + " WHERE scenarioId = ?";
    
    //Prepared statements
    private PreparedStatement psGetAllScenarios;
    private PreparedStatement psSaveScenario;
    private PreparedStatement psUpdateScenario;
    private PreparedStatement psDeleteScenario;
    
    //Connection
    private Connection connection;

    public ScenarioManager() {
        connection = DBConnector.getInstance().getDBConnection();
        initialiseStatements();
    }

    /**
     * Gets all scenarios from the database
     * @return ArrayList<Scenario>
     * @throws IllegalArgumentException 
     */
    @Override
    public ArrayList<Scenario> getScenarios() throws IllegalArgumentException {
        ArrayList<Scenario> allScenarios = new ArrayList<Scenario>();
        Scenario currentScenario;
        try {
            ResultSet results = psGetAllScenarios.executeQuery();
            while (results.next()) {
                currentScenario = new Scenario();
                currentScenario.setScenarioId(results.getInt("scenarioId"));
                currentScenario.setAlias(results.getNString("alias"));
                currentScenario.setDateCreated(results.getDate("dateCreated"));
                allScenarios.add(currentScenario);
            }

            results.close();
        } catch (SQLException ex) {
            System.err.println(ex);
        }
        return allScenarios;
    }

    /**
     * Saves scenario to the database or updates if it already exists
     * @param scenario
     * @throws IllegalArgumentException 
     */
    @Override
    public void saveScenario(Scenario scenario) throws IllegalArgumentException {
        int result = 0;
        try {
            if (scenario.getScenarioId() == 0) {
                psSaveScenario.setString(1, scenario.getAlias());
                result = psSaveScenario.executeUpdate();
                if (result != 0) {
                    scenario.setScenarioId(result);
                }
            } else {
                psUpdateScenario.setString(1, scenario.getAlias());
                psUpdateScenario.setInt(2, scenario.getScenarioId());
                result = psUpdateScenario.executeUpdate();
            }
        } catch (SQLException ex) {
            System.err.println(ex);
        }

        if (result == 0) {
            throw new IllegalArgumentException("Scenario save failed");
        }
    }

    /**
     * Deletes scenario from the database
     * @param scenario
     * @throws IllegalArgumentException 
     */
    @Override
    public void deleteScenario(Scenario scenario) throws IllegalArgumentException {
        try {
            psDeleteScenario.setInt(1, scenario.getScenarioId());
            if (psDeleteScenario.executeUpdate() == 0) {
                throw new IllegalArgumentException("Scenario doesn't exist");
            }
        } catch (SQLException ex) {
            System.err.print(ex);
        }
    }

    /**
     * Prepared statements initialisation
     */
    private void initialiseStatements() {
        try {
            psGetAllScenarios = connection.prepareStatement(GET_ALL_SCENARIOS);
            psSaveScenario = connection.prepareStatement(SAVE_SCENARIO);
            psUpdateScenario = connection.prepareStatement(UPDATE_SCENARIO);
            psDeleteScenario = connection.prepareStatement(DELETE_SCENARIO);
        } catch (SQLException ex) {
            System.err.print(ex);
        }
    }
}
